/**
 *******************************************************************************
 * @file      power_driver.c
 * @version   V1.0.0    
 * @date      2013.05.04
 * @brief     power driver for Taranis.
 *              GPIOD.00, MCU power control line for main power
 *              GPIOD.01, SWitch Status
 *              GPIOC.06, showing power status
 *              By checking switch status, report power switch
 *              By power control line, switch power On/Off
 * @author    - Adela 
 *            - Robert Zhang <armner@gmail.com>
 *            - 
 *
 */

#include "power_driver.h"
#include "stm32f2xx.h"


int power_open(Driver *driver)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* GPIOC GPIOD clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

    /* GPIO  Configuration*/
    GPIOD->BSRRL =GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    return 0;
}

/** @input 1: power on; 0: power off
 */
int power_write(Driver *driver, void *buffer, int len, OFFSET offset)
{
    char t;
    
    if(!len) return -1;
    
    t =*((char *)buffer);
    
    if(t)
    {
        GPIOD->BSRRH =GPIO_Pin_0;
    }
    else
    {
        GPIOD->BSRRL =GPIO_Pin_0;
    }
    
    return len;
}

/** @return  1: power switch on
 */
int power_read(Driver *driver, void *buffer, int len, OFFSET offset)
{
    if (!len) return -1;
    
    if(GPIOD->IDR &(1<<1))
    {
        *((char*)buffer) =0;
    }
    else
    {
        *((char*)buffer) =1;
    }
    
    return 1;
}

int power_io_control(Driver *driver, int io_type, int data)
{
    return 0;
}

int power_close(Driver *driver)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* GPIOC GPIOD clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

    /* GPIO  Configuration*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    return 0;
}

Driver power_driver=
{
    &power_open,
    &power_write,
    &power_read,
    &power_io_control,
    &power_close
};


